#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

#define Myself 1
const std::string blank_space = " ";
const std::string line_break = "\n";
// 编码
// "len""x op y"
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size());
    package += line_break;
    package += content;
    package += line_break;
    return package;
}
// 解码
// "len"\n"x op y"\n
bool Decode(std::string &package, std::string *content)
{
    // std::cout<<"package: "<<package<<std::endl;
    std::size_t pos = package.find(line_break);
    if (pos == std::string::npos)
        return false;
    std::string part_len = package.substr(0, pos);
    // std::cout << " part_len: " << part_len << std::endl;
    std::size_t len = std::stoi(part_len);
    // std::cout << "len" << len << std::endl;

    std::string part_content = package.substr(pos + 1, len);
    std::size_t in_total = part_len.size() + len + 2;
    if (package.size() > in_total)
        return false;
    *content = part_content;
    // erase部分

    package.erase(0, in_total);
    return true;
}

class Request
{
public:
    Request(int data1, int data2, char op)
        : x(data1), y(data2), oper(op)
    {
    }
    Request()
    {
    }
    ~Request()
    {
    }

public:
    // 序列化
    bool Serialization(std::string *out)
    {
#ifdef Myself
        // 构建报文的有效载荷 struct ->string "x op y"
        std::string s = std::to_string(x);
        s += blank_space;
        s += oper;
        s += blank_space;
        s += std::to_string(y);
        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["op"] = oper;
        root["y"] = y;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;

#endif
    }
    // 反序列化 "x op y"--->"x""op""y"
    // substr,find---利用string的接口
    bool Deserialization(const std::string &in)
    {
#ifdef Myself
        auto left = in.find(blank_space);
        if (left == std::string::npos)
            return false;
        auto part_x = in.substr(0, left);

        auto right = in.rfind(blank_space);
        if (right == std::string::npos)
            return false;
        auto part_y = in.substr(right + 1);

        // 检查
        if (left + 2 != right)
            return false;

        // std::cout << part_x << std::endl;
        x = std::stoi(part_x);
        // std::cout << x << std::endl;
        oper = in[left + 1];
        // std::cout << part_y << std::endl;

        y = std::stoi(part_y);
        // std::cout << y << std::endl;

        return true;
#else
    // 反序列化 "x op y"--->"x""op""y"
    Json::Value v;
    Json::Reader r;
    r.parse(in,v);
    x=v["x"].asInt();
    y=v["y"].asInt();
    oper=v["oper"].asInt();
    return true;
#endif
    }

    void DebugPrint()
    {
        std::cout << "请求构建成功：" << x << oper << y << "=?" << std::endl;
    }

public:
    int x;
    int y;
    char oper;
};

class Response
{
public:
    Response(int result, int code)
        : result_(result), code_(code)
    {
    }

    Response()
    {
    }
    ~Response()
    {
    }

public:
    // 序列化 --struct ->string "result code"
    bool Serialization(std::string *out)
    {
#ifdef Myself
        std::string s = std::to_string(result_);
        s += blank_space;
        s += std::to_string(code_);
        *out = s;

        return true;
#else
    Json::Value root;
    root["result_"]=result_;
    root["code_"]=code_;
    Json::StyledWriter w;
    *out=w.write(root);
    return true;
#endif
    }
    // 反序列化 "result""code"
    bool Deserialization(const std::string &in)
    {
#ifdef Myself
        auto pos = in.find(blank_space);
        if (pos == std::string::npos)
            return false;
        auto left = in.substr(0, pos);
        auto right = in.substr(pos + 1);

        result_ = std::stoi(left);
        code_ = std::stoi(right);
        return true;
#else
    Json::Value root;
    Json::Reader r;
    r.parse(in,root);
    result_=root["result_"].asInt();
    result_=root["result_"].asInt();
    return true;

#endif
    }

    void DebugPrint()
    {
        std::cout << "结果响应完成result:" << result_ << "code: " << code_ << std::endl;
    }

public:
    int result_;
    int code_;
};
